From c0aa821f0d62d539a85015e0c3d392194e673c92 Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Wed, 14 Jul 2004 15:36:10 +0000 Subject: [PATCH] bitkeeper revision 1.1081.1.1 (40f552eaWV4viomXWEuk8dzfLHid7g) Change to new restart model. --- .rootkeys | 1 + tools/examples/xmdefaults | 9 ++-- tools/examples/xmnetbsd | 10 ++-- tools/python/xen/xend/XendClient.py | 5 +- tools/python/xen/xend/XendDomain.py | 39 ++++++++------ tools/python/xen/xend/XendDomainInfo.py | 66 +++++++++++++---------- tools/python/xen/xend/server/SrvDomain.py | 10 +++- tools/python/xen/xm/create.py | 14 +++-- tools/python/xen/xm/destroy.py | 40 ++++++++++++++ tools/python/xen/xm/main.py | 9 ++-- 10 files changed, 138 insertions(+), 65 deletions(-) create mode 100644 tools/python/xen/xm/destroy.py diff --git a/.rootkeys b/.rootkeys index f11d07c06a..dc54a492ff 100644 --- a/.rootkeys +++ b/.rootkeys @@ -273,6 +273,7 @@ 40c9c469LNxLVizOUpOjEaTKKCm8Aw tools/python/xen/xend/sxp.py 40d05079aFRp6NQdo5wIh5Ly31c0cg tools/python/xen/xm/__init__.py 40cf2937gKQcATgXKGtNeWb1PDH5nA tools/python/xen/xm/create.py +40f552eariuUSB9TWqCPnDLz5zvxMw tools/python/xen/xm/destroy.py 40e41cd2w0I4En6qrJn4em8HkK_oxQ tools/python/xen/xm/help.py 40cf2937isyS250zyd0Q2GuEDoNXfQ tools/python/xen/xm/main.py 40cf2937PSslwBliN1g7ofDy2H_RhA tools/python/xen/xm/opts.py diff --git a/tools/examples/xmdefaults b/tools/examples/xmdefaults index 2c417a7cf8..ebb894d53e 100644 --- a/tools/examples/xmdefaults +++ b/tools/examples/xmdefaults @@ -91,8 +91,11 @@ root = "/dev/sda1 ro" extra = "4 VMID=%d usr=/dev/sda6" % vmid #---------------------------------------------------------------------------- -# Set according to whether you want the domain restarted when it exits. -# The default is False. -#autorestart = True +# Set according to whether you want the domain restarted when it exits. +# The default is 'onreboot', which restarts the domain when it shuts down +# with exit code reboot. +# Other values are 'always', and 'never'. + +#restart = 'onreboot' #============================================================================ diff --git a/tools/examples/xmnetbsd b/tools/examples/xmnetbsd index e62de6174e..f2a525d2e9 100644 --- a/tools/examples/xmnetbsd +++ b/tools/examples/xmnetbsd @@ -94,8 +94,10 @@ extra = "4 VMID=%d bootdev=xennet0" % vmid #---------------------------------------------------------------------------- -# Set according to whether you want the domain restarted when it exits. -# The default is False. -#autorestart = True - +# Set according to whether you want the domain restarted when it exits. +# The default is 'onreboot', which restarts the domain when it shuts down +# with exit code reboot. +# Other values are 'always', and 'never'. +# +#restart = 'onreboot' #============================================================================ diff --git a/tools/python/xen/xend/XendClient.py b/tools/python/xen/xend/XendClient.py index 91ba071dc0..538f84c3a9 100644 --- a/tools/python/xen/xend/XendClient.py +++ b/tools/python/xen/xend/XendClient.py @@ -256,9 +256,10 @@ class Xend: {'op' : 'shutdown', 'reason' : reason }) - def xend_domain_destroy(self, id): + def xend_domain_destroy(self, id, reason): return xend_call(self.domainurl(id), - {'op' : 'destroy' }) + {'op' : 'destroy', + 'reason' : reason }) def xend_domain_save(self, id, filename): return xend_call(self.domainurl(id), diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 2f0a7680c2..51d52f1acc 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -378,9 +378,9 @@ class XendDomain: def domain_shutdown(self, id, reason='poweroff'): """Shutdown domain (nicely). - - poweroff: domain will restart if has autorestart set. - - reboot: domain will restart. - - halt: domain will not restart (even if has autorestart set). + - poweroff: restart according to exit code and restart mode + - reboot: restart on exit + - halt: do not restart Returns immediately. @@ -388,12 +388,13 @@ class XendDomain: @param reason: shutdown type: poweroff, reboot, suspend, halt """ dom = int(id) + id = str(id) if dom <= 0: return 0 if reason == 'halt': self.domain_restart_cancel(id) else: - self.domain_restart_schedule(id, reason) + self.domain_restart_schedule(id, reason, set=1) eserver.inject('xend.domain.shutdown', [id, reason]) if reason == 'halt': reason = 'poweroff' @@ -401,21 +402,24 @@ class XendDomain: self.refresh_schedule() return val - def domain_restart_schedule(self, id, reason): + def domain_restart_schedule(self, id, reason, set=0): """Schedule a restart for a domain if it needs one. @param id: domain id @param reason: shutdown reason """ + print 'domain_restart_schedule>', id, reason, set dominfo = self.domain.get(id) - if not dominfo or id in self.restarts: - # Don't schedule if unknown or already there. + if not dominfo: + return + if id in self.restarts: return - restart = ((reason == 'reboot') or - (reason == 'poweroff' and dominfo.autorestart)) + if set and reason == 'reboot': + dominfo.restart_mode = XendDomainInfo.RESTART_ALWAYS + restart = dominfo.restart_needed(reason) if restart: - # Clear autorestart flag to avoid multiple restarts. - dominfo.autorestart = 0 + # Avoid multiple restarts. + dominfo.restart_mode = XendDomainInfo.RESTART_NEVER self.restarts[id] = dominfo.config print 'Scheduling restart for domain:', id, dominfo.name self.domain_restarts_schedule() @@ -427,7 +431,7 @@ class XendDomain: """ dominfo = self.domain.get(id) if dominfo: - dominfo.autorestart = 0 + dominfo.restart_mode = XendDomainInfo.RESTART_NEVER if id in self.restarts: del self.restarts[id] @@ -474,13 +478,18 @@ class XendDomain: val = xc.domain_destroy(dom=dom) return val - def domain_destroy(self, id): + def domain_destroy(self, id, reason='halt'): """Terminate domain immediately. - Cancels any restart for the domain. + - halt: cancel any restart for the domain + - reboot schedule a restart for the domain @param id: domain id """ - self.domain_restart_cancel(id) + id = str(id) + if reason == 'halt': + self.domain_restart_cancel(id) + elif reason == 'reboot': + self.domain_restart_schedule(id, reason, set=1) val = self.final_domain_destroy(id) self.refresh_schedule() return val diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index be7803f721..d63034f3ff 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -50,6 +50,16 @@ shutdown_reasons = { DOMAIN_REBOOT : "reboot", DOMAIN_SUSPEND : "suspend" } +RESTART_ALWAYS = 'always' +RESTART_ONREBOOT = 'onreboot' +RESTART_NEVER = 'never' + +restart_modes = [ + RESTART_ALWAYS, + RESTART_ONREBOOT, + RESTART_NEVER, + ] + def shutdown_reason(code): """Get a shutdown reason from a code. @@ -117,7 +127,12 @@ def lookup_disk_uname(uname): def make_disk(dom, uname, dev, mode, recreate=0): """Create a virtual disk device for a domain. - @returns Deferred + @param dom: domain id + @param uname: device to export + @param dev: device name in domain + @param mode: read/write mode + @param recreate: recreate flag (after xend restart) + @return: deferred """ segments = lookup_disk_uname(uname) if not segments: @@ -234,7 +249,6 @@ def vm_create(config): returns Deferred raises VmError for invalid configuration """ - print 'vm_create>' vm = XendDomainInfo() return vm.construct(config) @@ -289,28 +303,21 @@ def append_deferred(dlist, v): def _vm_configure1(val, vm): d = vm.create_devices() - #print '_vm_configure1> made devices...' def cbok(x): - #print '_vm_configure1> cbok', x return x d.addCallback(cbok) d.addCallback(_vm_configure2, vm) - #print '_vm_configure1<' return d def _vm_configure2(val, vm): - #print '>callback _vm_configure2...' d = vm.configure_fields() def cbok(results): - #print '_vm_configure2> cbok', results return vm def cberr(err): - #print '_vm_configure2> cberr', err vm.destroy() return err d.addCallback(cbok) d.addErrback(cberr) - #print '<_vm_configure2' return d class XendDomainInfo: @@ -341,7 +348,7 @@ class XendDomainInfo: #todo: set to migrate info if migrating self.migrate = None #Whether to auto-restart - self.autorestart = 0 + self.restart_mode = RESTART_ONREBOOT def setdom(self, dom): self.dom = int(dom) @@ -381,8 +388,7 @@ class XendDomainInfo: state = run + block + stop + susp + crash sxpr.append(['state', state]) if self.info['shutdown']: - reasons = ["poweroff", "reboot", "suspend"] - reason = reasons[self.info['shutdown_reason']] + reason = shutdown_reason(self.info['shutdown_reason']) sxpr.append(['shutdown_reason', reason]) sxpr.append(['cpu', self.info['cpu']]) sxpr.append(['cpu_time', self.info['cpu_time']/1e9]) @@ -398,8 +404,7 @@ class XendDomainInfo: try: self.name = sxp.child_value(config, 'name') self.memory = int(sxp.child_value(config, 'memory', '128')) - if sxp.child(config, 'autorestart', None): - self.autorestart = 1 + self.configure_restart() self.configure_backends() image = sxp.child_value(config, 'image') if image is None: @@ -413,7 +418,6 @@ class XendDomainInfo: image_handler(self, image) deferred = self.configure() def cbok(x): - print 'vm_create> cbok', x return x def cberr(err): self.destroy() @@ -424,7 +428,6 @@ class XendDomainInfo: # Catch errors, cleanup and re-raise. self.destroy() raise - print 'vm_create<' return deferred def config_devices(self, name): @@ -514,7 +517,6 @@ class XendDomainInfo: def cleanup(self): """Cleanup vm resources: release devices. """ - print 'cleanup>', self.dom self.state = self.STATE_TERMINATED self.release_devices() @@ -526,7 +528,6 @@ class XendDomainInfo: def release_devices(self): """Release all vm devices. """ - print 'release_devices>', self.dom self.release_vifs() self.release_vbds() self.devices = {} @@ -534,7 +535,6 @@ class XendDomainInfo: def release_vifs(self): """Release vm virtual network devices (vifs). """ - print 'release_vifs>', self.dom if self.dom is None: return ctrl = xend.netif_get(self.dom) if ctrl: @@ -543,7 +543,6 @@ class XendDomainInfo: def release_vbds(self): """Release vm virtual block devices (vbds). """ - print 'release_vbds>', self.dom if self.dom is None: return ctrl = xend.blkif_get(self.dom) if ctrl: @@ -574,7 +573,7 @@ class XendDomainInfo: memory = self.memory name = self.name cpu = int(sxp.child_value(self.config, 'cpu', '-1')) - print 'init_domain>', memory, name, cpu + #print 'init_domain>', memory, name, cpu dom = xc.domain_create(mem_kb= memory * 1024, name= name, cpu= cpu) if dom <= 0: raise VmError('Creating domain failed: name=%s memory=%d' @@ -589,7 +588,7 @@ class XendDomainInfo: print 'Warning: kernel cmdline too long' dom = self.dom buildfn = getattr(xc, '%s_build' % ostype) - print 'build_domain>', ostype, dom, kernel, cmdline, ramdisk + #print 'build_domain>', ostype, dom, kernel, cmdline, ramdisk flags = 0 if self.netif_backend: flags |= SIF_NET_BE_DOMAIN if self.blkif_backend: flags |= SIF_BLK_BE_DOMAIN @@ -612,15 +611,12 @@ class XendDomainInfo: cmdline kernel commandline vifs_n number of network interfaces """ - print 'create_domain>', ostype, kernel if not self.recreate: if not os.path.isfile(kernel): raise VmError('Kernel image does not exist: %s' % kernel) if ramdisk and not os.path.isfile(ramdisk): raise VmError('Kernel ramdisk does not exist: %s' % ramdisk) - print 'create-domain> init_domain...' self.init_domain() - print 'create_domain>', 'dom=', self.dom self.console = xendConsole.console_create(self.dom) self.build_domain(ostype, kernel, ramdisk, cmdline, vifs_n) self.image = kernel @@ -633,7 +629,6 @@ class XendDomainInfo: returns Deferred raises VmError for invalid devices """ - print '>create_devices' dlist = [] devices = sxp.children(self.config, 'device') index = {} @@ -650,7 +645,6 @@ class XendDomainInfo: append_deferred(dlist, v) index[dev_name] = dev_index + 1 deferred = defer.DeferredList(dlist, fireOnOneErrback=1) - print ' created', dev return id defer.addCallback(fn) return defer diff --git a/tools/python/xen/xend/server/SrvDomain.py b/tools/python/xen/xend/server/SrvDomain.py index a3ec017622..eed90b7feb 100644 --- a/tools/python/xen/xend/server/SrvDomain.py +++ b/tools/python/xen/xend/server/SrvDomain.py @@ -50,7 +50,10 @@ class SrvDomain(SrvDir): return val def op_destroy(self, op, req): - val = self.xd.domain_destroy(self.dom.id) + fn = FormFn(self.xd.domain_destroy, + [['dom', 'int'], + ['reason', 'str']]) + val = fn(req.args, {'dom': self.dom.id}) req.setHeader("Location", "%s/.." % req.prePathURL()) return val @@ -220,7 +223,12 @@ class SrvDomain(SrvDir): req.write('
' % url) req.write('') req.write('') + req.write('
') + + req.write('
' % url) req.write('') + req.write('Halt') + req.write('Reboot') req.write('
') req.write('
' % url) diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index c4e2567fe2..7c9dcb3db8 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -97,9 +97,13 @@ gopts.var('memory', val='MEMORY', fn=set_value, default=128, use="Domain memory in MB.") -gopts.var('autorestart', val='no|yes', - fn=set_bool, default=0, - use="Whether to restart the domain on exit.") +gopts.var('restart', val='onreboot|always|never', + fn=set_value, default=None, + use="""Whether the domain should be restarted on exit. + - onreboot: restart on exit with shutdown code reboot + - always: always restart on exit, ignore exit code + - never: never restart on exit, ignore exit code + """) gopts.var('blkif', val='no|yes', fn=set_bool, default=0, @@ -294,8 +298,8 @@ def make_config(vals): config.append(['backend', ['blkif']]) if vals.netif: config.append(['backend', ['netif']]) - if vals.autorestart: - config.append(['autorestart']) + if vals.restart: + config.append(['restart', vals.restart]) configure_image(config, vals) config_devs = [] diff --git a/tools/python/xen/xm/destroy.py b/tools/python/xen/xm/destroy.py new file mode 100644 index 0000000000..73df69d569 --- /dev/null +++ b/tools/python/xen/xm/destroy.py @@ -0,0 +1,40 @@ +# Copyright (C) 2004 Mike Wray + +"""Destroy a domain. +""" + +from xen.xend.XendClient import server +from xen.xm.opts import * + +gopts = Opts(use="""[options] [DOM] + +Destroy a domain, optionally restarting it. +""") + +gopts.opt('help', short='h', + fn=set_true, default=0, + use="Print this help.") + +gopts.opt('reboot', short='R', + fn=set_true, default=0, + use='Destroy and restart.') + +def main(argv): + opts = gopts + args = opts.parse(argv) + if opts.vals.help: + opts.usage() + return + if len(args) < 1: opts.err('Missing domain') + dom = args[0] + try: + domid = int(dom) + except: + opts.err('Invalid domain: ' + dom) + if opts.vals.reboot: + mode = 'reboot' + else: + mode = 'halt' + server.xend_domain_destroy(domid, mode) + + diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index e624447955..5c1c544073 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -11,7 +11,7 @@ from xen.xend import PrettyPrint from xen.xend import sxp from xen.xend.XendClient import XendError, server from xen.xend.XendClient import main as xend_client_main -from xen.xm import create, shutdown +from xen.xm import create, destroy, shutdown class Prog: """Base class for sub-programs. @@ -268,13 +268,10 @@ class ProgDestroy(Prog): info = """Terminate a domain immediately.""" def help(self, args): - print args[0], 'DOM' - print '\nTerminate domain DOM immediately.' + destroy.main([args[0], '-h']) def main(self, args): - if len(args) < 2: self.err("%s: Missing domain" % args[0]) - dom = args[1] - server.xend_domain_destroy(dom) + destroy.main(args) xm.prog(ProgDestroy) -- 2.30.2